#include "can.h"

//接收标志位
// 0x01表示CAN1中断接收
// 0x02表示CAN2中断接收
// 0x03表示有CAN1和CAN2中断接收

uint8_t Flag_CAN_Rx = 0x00;
//每8位为一组，按ID顺序放置数据,实际电机值只会返回6个字节，这里多设置两个字节方便调试
uint8_t CAN1_Rx_Data[24];
uint8_t CAN2_Rx_Data[24];

/*******************************CAN1 interrupt function**********************************/
/**
 *  @brief  can1 interrupt function rx0,读取数据到临时的数据区
 *  @param  none
 *  @retval none
 */
void USBFS_L_CAN1_RX0_IRQHandler(void)
{
  can_rx_message_type rx_message_struct;
  if (can_flag_get(CAN1, CAN_RF0MN_FLAG) != RESET)
  {
    can_message_receive(CAN1, CAN_RX_FIFO0, &rx_message_struct);
    if (rx_message_struct.standard_id == Motor1_CAN_ID)
    {
      for (int i = 0; i < 8; i++)
      {
        CAN1_Rx_Data[i] = rx_message_struct.data[i];
      }
      Flag_CAN_Rx|=Flag_CAN1_ID1;
				
    }
    if (rx_message_struct.standard_id == Motor2_CAN_ID)
    {
      for (int i = 0; i < 8; i++)
      {
        CAN1_Rx_Data[i + 8] = rx_message_struct.data[i];
      }
      Flag_CAN_Rx|=Flag_CAN1_ID2;
    }
    if (rx_message_struct.standard_id == Motor3_CAN_ID)
    {
      for (int i = 0; i < 8; i++)
      {
        CAN1_Rx_Data[i + 16] = rx_message_struct.data[i];
      }
      Flag_CAN_Rx|=Flag_CAN1_ID3;
    }
		//printf("CAN1 ID:%d\r\n",rx_message_struct.standard_id);
    LED_OFF();
	
  }
}

/**
 *  @brief  can1 interrupt function se
 *  @param  none
 *  @retval none
 */
void CAN1_SE_IRQHandler(void)
{
  __IO uint32_t err_index = 0;
  if (can_flag_get(CAN1, CAN_ETR_FLAG) != RESET)
  {
    err_index = CAN1->ests & 0x70;

    /* error type is stuff error */
    if (err_index == 0x00000010)
    {
      printf("CAN1 error type is stuff error\r\n");
      /* when stuff error occur: in order to ensure communication normally,
      user must restart can or send a frame of highest priority message here */
    }
    //printf("CAN1 error:%x\r\n", err_index);
    can_flag_clear(CAN1, CAN_ETR_FLAG);
  }
}

/*******************************CAN2 interrupt function**********************************/

/**
 *  @brief  can2 interrupt function rx0,读取数据到临时的数据区
 *  @param  none
 *  @retval none
 */
void CAN2_RX0_IRQHandler(void)
{
  can_rx_message_type rx_message_struct;
  if (can_flag_get(CAN2, CAN_RF0MN_FLAG) != RESET)
  {
    can_message_receive(CAN2, CAN_RX_FIFO1, &rx_message_struct);
    if (rx_message_struct.standard_id == Motor1_CAN_ID)
    {
      for (int i = 0; i < 8; i++)
      {
        CAN2_Rx_Data[i] = rx_message_struct.data[i];

      }
        Flag_CAN_Rx|=Flag_CAN2_ID1;

    }
    if (rx_message_struct.standard_id == Motor2_CAN_ID)
    {
      for (int i = 0; i < 8; i++)
      {
        CAN2_Rx_Data[i + 8] = rx_message_struct.data[i];
      }
        Flag_CAN_Rx|=Flag_CAN2_ID2;

    }
    if (rx_message_struct.standard_id == Motor3_CAN_ID)
    {
      for (int i = 0; i < 8; i++)
      {
        CAN2_Rx_Data[i + 16] = rx_message_struct.data[i];
      }
        Flag_CAN_Rx|=Flag_CAN2_ID3;

    }
    LED_OFF();
  }
}

/**
 *  @brief  can2 interrupt function se
 *  @param  none
 *  @retval none
 */
void CAN2_SE_IRQHandler(void)
{
  __IO uint32_t err_index = 0;
  if (can_flag_get(CAN2, CAN_ETR_FLAG) != RESET)
  {
    err_index = CAN2->ests & 0x70;

    /* error type is stuff error */
    if (err_index == 0x00000010)
    {
      printf("CAN2 error type is stuff error\r\n");
      /* when stuff error occur: in order to ensure communication normally,
      user must restart can or send a frame of highest priority message here */
    }
    // printf("CAN2 error:%d\r\n", err_index);
    can_flag_clear(CAN2, CAN_ETR_FLAG);
  }
}

void can1_gpio_config(void)
{
  gpio_init_type gpio_init_struct;

  gpio_default_para_init(&gpio_init_struct);
  /* can tx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = GPIO_PINS_12;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOA, &gpio_init_struct);
  /* can rx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  gpio_init_struct.gpio_pins = GPIO_PINS_11;
  gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  gpio_init(GPIOA, &gpio_init_struct);
}

void can2_gpio_config(void)
{
  gpio_init_type gpio_init_struct;

  gpio_default_para_init(&gpio_init_struct);
  /* can tx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = GPIO_PINS_13;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOB, &gpio_init_struct);
  /* can rx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  gpio_init_struct.gpio_pins = GPIO_PINS_12;
  gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  gpio_init(GPIOB, &gpio_init_struct);
}

void can1_configuration(void)
{
  can1_gpio_config();

  can_base_type can_base_struct;
  can_baudrate_type can_baudrate_struct;
  can_filter_init_type can_filter_init_struct;

  /* can base init */
  can_default_para_init(&can_base_struct);
  can_base_struct.mode_selection = CAN_MODE_COMMUNICATE;
  can_base_struct.ttc_enable = FALSE;
  can_base_struct.aebo_enable = TRUE;
  can_base_struct.aed_enable = TRUE;
  can_base_struct.prsf_enable = FALSE;
  can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED;
  can_base_struct.mmssr_selection = CAN_SENDING_BY_ID;
  can_base_init(CAN1, &can_base_struct);

  /* can baudrate, set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size)) */
  can_baudrate_struct.baudrate_div = 10;
  can_baudrate_struct.rsaw_size = CAN_RSAW_3TQ;
  can_baudrate_struct.bts1_size = CAN_BTS1_8TQ;
  can_baudrate_struct.bts2_size = CAN_BTS2_3TQ;
  can_baudrate_set(CAN1, &can_baudrate_struct);

  /* can filter init */
  can_filter_init_struct.filter_activate_enable = TRUE;
  can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
  can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
  can_filter_init_struct.filter_number = 0;
  can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
  can_filter_init_struct.filter_id_high = 0;
  can_filter_init_struct.filter_id_low = 0;
  can_filter_init_struct.filter_mask_high = 0;
  can_filter_init_struct.filter_mask_low = 0;
  can_filter_init(CAN1, &can_filter_init_struct);

  /* can interrupt config */
  nvic_irq_enable(CAN1_SE_IRQn, 0x00, 0x00);
  nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn, 0x00, 0x00);
  can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);

  /* error interrupt enable */
  can_interrupt_enable(CAN1, CAN_ETRIEN_INT, TRUE);
  can_interrupt_enable(CAN1, CAN_EOIEN_INT, TRUE);
}

void can2_configuration(void)
{
  can2_gpio_config();

  can_base_type can_base_struct;
  can_baudrate_type can_baudrate_struct;
  can_filter_init_type can_filter_init_struct;

  /* can base init */
  can_default_para_init(&can_base_struct);
  can_base_struct.mode_selection = CAN_MODE_COMMUNICATE;
  can_base_struct.ttc_enable = FALSE;
  can_base_struct.aebo_enable = TRUE;
  can_base_struct.aed_enable = TRUE;
  can_base_struct.prsf_enable = FALSE;
  can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED;
  can_base_struct.mmssr_selection = CAN_SENDING_BY_ID;
  can_base_init(CAN2, &can_base_struct);

  /* can baudrate, set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size)) */
  can_baudrate_struct.baudrate_div = 10;
  can_baudrate_struct.rsaw_size = CAN_RSAW_3TQ;
  can_baudrate_struct.bts1_size = CAN_BTS1_8TQ;
  can_baudrate_struct.bts2_size = CAN_BTS2_3TQ;
  can_baudrate_set(CAN2, &can_baudrate_struct);

  /* can filter init */
  can_filter_init_struct.filter_activate_enable = TRUE;
  can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
  can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
  can_filter_init_struct.filter_number = 0;
  can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
  can_filter_init_struct.filter_id_high = 0;
  can_filter_init_struct.filter_id_low = 0;
  can_filter_init_struct.filter_mask_high = 0;
  can_filter_init_struct.filter_mask_low = 0;
  can_filter_init(CAN2, &can_filter_init_struct);

  /* can interrupt config */
  nvic_irq_enable(CAN2_SE_IRQn, 0x00, 0x01);
  nvic_irq_enable(CAN2_RX0_IRQn, 0x00, 0x01);
  can_interrupt_enable(CAN2, CAN_RF0MIEN_INT, TRUE);

  /* error interrupt enable */
  can_interrupt_enable(CAN2, CAN_ETRIEN_INT, TRUE);
  can_interrupt_enable(CAN2, CAN_EOIEN_INT, TRUE);
}

void CAN_Init(void)
{
  can1_configuration();
  can2_configuration();
}

// CAN发送函数
void CAN_Send(can_type *CAN, uint16_t ID, uint8_t *CAN_DATA)
{
  uint8_t transmit_mailbox;
  can_tx_message_type tx_message_struct;
  tx_message_struct.standard_id = ID;
  tx_message_struct.extended_id = 0;
  tx_message_struct.id_type = CAN_ID_STANDARD;
  tx_message_struct.frame_type = CAN_TFT_DATA;
  tx_message_struct.dlc = 8;
  for (uint8_t i = 0; i < 8; i++)
  {
    tx_message_struct.data[i] = CAN_DATA[i];
  }
  transmit_mailbox = can_message_transmit(CAN, &tx_message_struct);
}